﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using System.Collections.ObjectModel;
using System.Windows.Forms;
using System.IO;
using System.Threading;

namespace XMM
{
    /// <summary>
    /// Interaktionslogik für ImportMedia.xaml
    /// </summary>
    public partial class ImportMedia : Window
    {
        /// <summary>
        /// Collection of found Files to use as ItemSource for lvFoundItems.
        /// </summary>
        public ObservableCollection<Objects.MediaInfo> _FileCollection = new ObservableCollection<Objects.MediaInfo>();

        /// <summary>
        /// Reference to the Collection of found Files.
        /// </summary>
        public ObservableCollection<Objects.MediaInfo> FileCollection
        { get { return _FileCollection; } }

        /// <summary>
        /// Selected Target-Directory.
        /// </summary>
        DirectoryInfo diSelectedRootDirectory;

        /// <summary>
        /// Marker for running Directory-Processing-Thread.
        /// </summary>
        private bool IsProcessing = false;

        /// <summary>
        /// Directory-Processing-Thread.
        /// </summary>
        Thread thProcessingThread;

        /// <summary>
        /// Access-Control for the Directory-Processing-Thread.
        /// </summary>
        Mutex mutProcessingThread = new Mutex();

        /// <summary>
        /// True if user selected to search within subdirectories.
        /// </summary>
        private bool CheckSubdirectories = false;

        /// <summary>
        /// True if permission-exception was catched.
        /// </summary>
        /// <remarks>used to abort scanning of other extensions within processing-thread.</remarks>
        private bool PermissionException = false;

        /// <summary>
        /// User-Selected MediaItem in lvFoundItems.
        /// </summary>
        public Objects.MediaInfo SelectedMediaItem { get; set; }


        private Library ParentMainWindow;

        private Mutex mutPrefetchShows;

        public Mutex PrefetchShowsStatus { get { return mutPrefetchShows; } }

        /// <summary>
        /// List of existing Shows.
        /// </summary>
        public ObservableCollection<Objects.Series> _AvailableSeries = new ObservableCollection<Objects.Series>();

        public bool IsPrefetching { get; set; }

        /// <summary>
        /// Referer to list of existing Shows - used for Series-Selector.
        /// </summary>
        private ObservableCollection<Objects.Series> AvailableSeries
        {
            get
            {
                return _AvailableSeries;
            }
        }

        /// <summary>
        /// Initialize a new ImportMedia()-Dialoge.
        /// </summary>
        public ImportMedia(Library dlgParentMainWindow)
        {
            InitializeComponent();

            mutPrefetchShows = new Mutex();
            ParentMainWindow = dlgParentMainWindow;
        }

        /// <summary>
        /// Pre-Fetch Data
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            startPrefetchShows();
        }

        public void startPrefetchShows()
        {
            // Prefetch Shows
            Thread thPrefetchShows = new Thread(new ThreadStart(prefetchShows));
            thPrefetchShows.Start();
        }

        /// <summary>
        /// Prefetch Shows.
        /// </summary>
        private void prefetchShows()
        {
            if (mutPrefetchShows.WaitOne(500))
            {
                IsPrefetching = true;
                Dispatcher.Invoke(new updateStatusCallback(updateStatus), new object[] { 0, "Lade verfügbare Serien..." });
                _AvailableSeries = new ObservableCollection<Objects.Series>();
                List<Objects.Series> lSeries = Objects.Series.getAllSeries();

                int iShowPercentage = 0;
                if(lSeries.Count != 0)
                    iShowPercentage = (int)Math.Round(((decimal)100 / lSeries.Count), 0);

                int iCurrentShow = 1;

                if (lSeries != null && lSeries.Count > 0)
                {
                    foreach (Objects.Series oSeries in lSeries)
                    {
                        int iCurrentPercentage = iCurrentShow * iShowPercentage;
                        if (iCurrentPercentage > 100)
                            iCurrentPercentage = 100;

                        Dispatcher.Invoke(new updateStatusCallback(updateStatus), new object[] { iCurrentPercentage, "Lade Serie " + iCurrentShow.ToString() + " of " + lSeries.Count.ToString() + "..." });
                        _AvailableSeries.Add(oSeries);

                        ++iCurrentShow;
                    }
                }

                Dispatcher.Invoke(new updateStatusCallback(updateStatus), new object[] { 0, "Bereit..." });
                IsPrefetching = false;

                // Release Prefetch-Mutex.
                mutPrefetchShows.ReleaseMutex();
            }
        }

        /// <summary>
        /// Browse for Target-Directory.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        /// <remarks>Using System.Windows.Forms.FolderBrowserDialog()!!</remarks>
        private void btnBrowse_Click(object sender, RoutedEventArgs e)
        {
            FolderBrowserDialog dlgBrowseTarget = new FolderBrowserDialog();
            if (dlgBrowseTarget.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                txtTargetFolder.Text = dlgBrowseTarget.SelectedPath;
                processFiles();
            }
        }

        /// <summary>
        /// Prepare values for directory-processing.
        /// </summary>
        public void processFiles()
        {
            IsProcessing = true;
            CheckSubdirectories = (bool)chkSubdirectories.IsChecked;
            toggleControls();

            pbStatus.Value = 0;
            lblStatus.Content = "Analysiere \"" + txtTargetFolder.Text + "\"...";

            try
            {
                // Setup Directory-Info for Target-Directory.
                diSelectedRootDirectory = new DirectoryInfo(txtTargetFolder.Text);

                // Kill running processing-thread if available.
                if (thProcessingThread != null)
                {
                    thProcessingThread.Abort();
                }

                // Check if target-directory-info is valid.
                if (diSelectedRootDirectory != null)
                {
                    // Start new Processing-Thread.
                    thProcessingThread = new Thread(new ThreadStart(doProcessing));
                    thProcessingThread.Start();
                }
            }
            catch (Exception ex)
            {
                System.Windows.MessageBox.Show("Beim Analysieren des angegebenen Verzeichnisses ist ein Fehler aufgetretten: " + ex.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error);
            }
        }

        /// <summary>
        /// Do actual Processing of files in target directory (start in seperate Thread).
        /// </summary>
        private void doProcessing()
        {
            if (mutProcessingThread.WaitOne(2000))
            {
                // Setup Variables.
                List<Objects.SupportedExtension> lSupportedExtensions = Objects.SupportedExtension.getAllExtensions();
                this.Dispatcher.Invoke(new resetListItemsCallback(resetListItems));
                this.Dispatcher.Invoke(new setPermissionExceptionCallback(setPermissionException), new object[] { false });

                // Check if any supported extensions are available.
                if (lSupportedExtensions != null && lSupportedExtensions.Count > 0)
                {
                    // Foreach supported extension, do a scan for available files within targetdirectory.
                    foreach (Objects.SupportedExtension oExtension in lSupportedExtensions)
                    {
                        // Check if extension-info is valid.
                        if (oExtension.ExtensionID != 0)
                        {
                            // Configure Search-Option for subdirectories.
                            SearchOption oFileSearchOptions = SearchOption.TopDirectoryOnly;
                            if (CheckSubdirectories)
                                oFileSearchOptions = SearchOption.AllDirectories;

                            // Get files with matching extension.
                            FileInfo[] fiaFoundMediaItems = getMediaItems(oExtension, oFileSearchOptions);

                            // Add found files (if any) to global MediaInfo-List.
                            if (fiaFoundMediaItems != null && fiaFoundMediaItems.Count() > 0)
                            {
                                // Setup Status-Values.
                                int iTotalItems = fiaFoundMediaItems.Count();
                                decimal dPercentPerItem = 100 / iTotalItems;
                                int iCurrentItem = 1;

                                foreach (FileInfo fiFoundItem in fiaFoundMediaItems)
                                {
                                    // Generate MediaInfo()-object from file-infos.
                                    Objects.MediaInfo oMediaInfo = new XMM.Objects.MediaInfo();
                                    oMediaInfo.FullPath = fiFoundItem.FullName;

                                    if (ItemChecks.checkFileExists(oMediaInfo.FullPath) == false)
                                    {
                                        oMediaInfo.MediaType = oExtension.MediaType;
                                        oMediaInfo.FileName = fiFoundItem.Name;
                                        oMediaInfo.DirectoryName = fiFoundItem.DirectoryName;
                                        oMediaInfo.UserdefinedMediaInfo = null;

                                        // Add to list...
                                        this.Dispatcher.Invoke(new addMediaItemCallback(addMediaItem), new object[] { oMediaInfo });
                                    }
                                    // Update Status;
                                    this.Dispatcher.Invoke(new updateStatusCallback(updateStatus), new object[] { (int)Math.Floor(iCurrentItem * dPercentPerItem), "Lade Datei " + iCurrentItem.ToString() + " von " + iTotalItems.ToString() + "..." });
                                    ++iCurrentItem;
                                }
                            }
                        }
                    }
                }

                // Reset values & GUI.
                this.Dispatcher.Invoke(new setPermissionExceptionCallback(setPermissionException), new object[] { false });
                this.Dispatcher.Invoke(new updateStatusCallback(updateStatus), new object[] { 0, "Bereit..." });
                this.Dispatcher.Invoke(new setIsProcessingCallback(setIsProcessing), new object[] { false });
                this.Dispatcher.Invoke(new toggleControlsCallback(toggleControls));
                mutProcessingThread.ReleaseMutex();
            }
        }

        /// <summary>
        /// Set marker for running directory-processing-thread.
        /// </summary>
        /// <param name="bIsProcessing"></param>
        private void setIsProcessing(bool bIsProcessing)
        {
            IsProcessing = bIsProcessing;
        }

        /// <summary>
        /// Set marker for running directory-processing-thread. (CALLBACK)
        /// </summary>
        /// <param name="bIsProcessing"></param>
        private delegate void setIsProcessingCallback(bool bIsProcessing);

        /// <summary>
        /// Set marker for catched permission-exception.
        /// </summary>
        /// <param name="bExceptionStatus"></param>
        private void setPermissionException(bool bExceptionStatus)
        {
            PermissionException = bExceptionStatus;
        }

        /// <summary>
        /// Set marker for catched permission-exception. (CALLBACK)
        /// </summary>
        /// <param name="bExceptionStatus"></param>
        private delegate void setPermissionExceptionCallback(bool bExceptionStatus);

        /// <summary>
        /// Reset ItemSource for lvFoundItems.
        /// </summary>
        private void resetListItems()
        {
            _FileCollection = new ObservableCollection<XMM.Objects.MediaInfo>();
        }

        /// <summary>
        /// Reset ItemSource for lvFoundItems. (CALLBACK)
        /// </summary>
        private delegate void resetListItemsCallback();

        /// <summary>
        /// Get FileInfo-Array from filescan.
        /// </summary>
        /// <param name="oExtension">(Objects.Extension) File-Extension to scan for.</param>
        /// <param name="oFileSearchOptions">(SearchOption) Search-Option with subdirectory-processing-configuration.</param>
        /// <returns></returns>
        private FileInfo[] getMediaItems(Objects.SupportedExtension oExtension, SearchOption oFileSearchOptions)
        {
            FileInfo[] fiaFoundMediaItems = null;

            if (PermissionException == false)
            {
                try
                {
                    fiaFoundMediaItems = diSelectedRootDirectory.GetFiles("*." + oExtension.Extension, oFileSearchOptions);
                }
                catch (UnauthorizedAccessException ex)
                {
                    System.Windows.MessageBox.Show("Fehler beim Analysieren eines Verzeichnisses: " + ex.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error);
                    PermissionException = true;
                }
                catch (DirectoryNotFoundException ex)
                {
                    System.Windows.MessageBox.Show("Der Pfad oder ein Unterverzeichnis kann nicht vollständig aufgelöst werden: " + ex.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error);
                }
            }

            return fiaFoundMediaItems;
        }

        /// <summary>
        /// Add MediaInfo-Object to lvFoundItems.
        /// </summary>
        /// <param name="oMediaInfo">(Objects.MediaInfo) MediaInfo-Object for a found MediaItem.</param>
        private void addMediaItem(Objects.MediaInfo oMediaInfo)
        {
            _FileCollection.Add(oMediaInfo);
        }

        /// <summary>
        /// Add MediaInfo-Object to lvFoundItems. (CALLBACK)
        /// </summary>
        /// <param name="oMediaInfo">(Objects.MediaInfo) MediaInfo-Object for a found MediaItem.</param>
        private delegate void addMediaItemCallback(Objects.MediaInfo oMediaInfo);

        /// <summary>
        /// Update Status-Info.
        /// </summary>
        /// <param name="iNewProgress">(int) new Value for ProgressBar (0-100).</param>
        /// <param name="sNewMessage">(string) new Status-Message.</param>
        private void updateStatus(int iNewProgress, string sNewMessage)
        {
            // Reset Progress-Values if exceeds 100.
            if (iNewProgress > 100)
                iNewProgress = 100;

            pbStatus.Value = iNewProgress;
            lblStatus.Content = sNewMessage;

            int iDebug = lvFoundItems.Items.Count;

            lvFoundItems.ItemsSource = FileCollection;
            lvFoundItems.ItemsPanel.LoadContent();
        }

        /// <summary>
        /// Update Status-Info. (CALLBACK)
        /// </summary>
        /// <param name="iNewProgress">(int) new Value for ProgressBar (0-100).</param>
        /// <param name="sNewMessage">(string) new Status-Message.</param>
        private delegate void updateStatusCallback(int iNewProgress, string sNewMessage);

        /// <summary>
        /// Toggle Control-Elements.
        /// </summary>
        /// <remarks>Enable User-Controls while idle and disable during loading and processing.</remarks>
        public void toggleControls()
        {
            if (IsProcessing)
            {
                txtTargetFolder.IsEnabled = false;
                btnBrowse.IsEnabled = false;
                chkSubdirectories.IsEnabled = false;
                spnMediaType.IsEnabled = false;
                spnMediaType.Visibility = Visibility.Collapsed;
            }
            else
            {
                txtTargetFolder.IsEnabled = true;
                btnBrowse.IsEnabled = true;
                chkSubdirectories.IsEnabled = true;
            }
        }

        /// <summary>
        /// Toggle Control-Elements.
        /// </summary>
        private delegate void toggleControlsCallback();

        /// <summary>
        /// Toggle MediaTypeSelector-Panel visibility.
        /// </summary>
        private void toggleMediaTypeSelector()
        {
            if (SelectedMediaItem != null)
            {
                spnMediaType.IsEnabled = true;
                spnMediaType.Visibility = Visibility.Visible;
            }
            else
            {
                spnMediaType.IsEnabled = false;
                spnMediaType.Visibility = Visibility.Collapsed;
            }
        }

        /// <summary>
        /// Toggle MediaTypeSelector-Panel visibility. (CALLBACK)
        /// </summary>
        private delegate void toggleMediaTypeSelectorCallback();

        /// <summary>
        /// Marker if values is preloaded by processing-chain, not by user.
        /// </summary>
        private bool bPreloading = false;

        /// <summary>
        /// User selected different item in lvFoundItems.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void lvFoundItems_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (lvFoundItems.SelectedItem != null)
            {
                bPreloading = true;
                SelectedMediaItem = (Objects.MediaInfo)lvFoundItems.SelectedItem;
                toggleMediaTypeSelector();
                setTypeSelection(SelectedMediaItem.MediaType);
                showEditor();
                bPreloading = false;
            }
            else
            {
                SelectedMediaItem = null;
            }
        }

        /// <summary>
        /// Show MediaInfo-Editor.
        /// </summary>
        private void showEditor()
        {
            spnItemDetails.Children.Clear();

            if (SelectedMediaItem != null)
            {
                if (ItemChecks.checkFileExists(SelectedMediaItem.FullPath))
                {
                    string sExistingItemDescription = String.Empty;
                    //int iExistingItemID = 0;

                    switch (SelectedMediaItem.MediaType)
                    {
                        case 1:
                            Objects.Movie oMovie = getExistingMovieInfo(SelectedMediaItem.FullPath);
                            sExistingItemDescription = "Film \"" + oMovie.Name + "\" (" + oMovie.Year.ToString() + "), ID '" + oMovie.MovieID.ToString() + "'";
                            break;
                        case 2:
                            break;
                    }

                    System.Windows.Controls.Label lblItemPresent = new System.Windows.Controls.Label();
                    lblItemPresent.Content = "Datei bereits erfasst: " + sExistingItemDescription;
                }
                else
                {
                    switch (SelectedMediaItem.MediaType)
                    {
                        case 1:
                            showMovieEditor();
                            break;
                        case 2:
                            showEpisodeEditor();
                            break;
                    }
                }
            }
        }

        /// <summary>
        /// Get a Movie-Object for an existing movie from it's file-path.
        /// </summary>
        /// <param name="sFullPath">(string) Full path to any linked video-file.</param>
        /// <returns>(Objects.Movie) Target-Movie-Item if found else [null].</returns>
        private Objects.Movie getExistingMovieInfo(string sFullPath)
        {
            Objects.Movie oMovie = new Objects.Movie(sFullPath);
            if (oMovie != null && oMovie.MovieID != 0)
            {
                return oMovie;
            }

            return null;
        }

        /// <summary>
        /// Show MediaInfo-Editor for movies.
        /// </summary>
        private void showMovieEditor()
        {
            Controls.Library.Import_Movie ctlMovieEditor = new XMM.Controls.Library.Import_Movie(this, SelectedMediaItem);
            spnItemDetails.Children.Add(ctlMovieEditor);

            ctlMovieEditor.ctlAudioInfo.SelectedFilePath = SelectedMediaItem.FullPath;
            ctlMovieEditor.ctlVideoInfo.SelectedFilePath = SelectedMediaItem.FullPath;

            // Get Movie-Info.
            if (SelectedMediaItem.UserdefinedMediaInfo == null || SelectedMediaItem.UserdefinedMediaInfo.GetType() != typeof(Objects.Movie))
            {
                SelectedMediaItem.UserdefinedMediaInfo = new Objects.Movie();
                ((Objects.Movie)SelectedMediaItem.UserdefinedMediaInfo).Files.Add(SelectedMediaItem.FullPath);
            }
            
            Objects.Movie oSelectedMovie = (Objects.Movie)SelectedMediaItem.UserdefinedMediaInfo;

            if (oSelectedMovie == null || oSelectedMovie.Name == String.Empty)
            {
                oSelectedMovie = new Objects.Movie();
                oSelectedMovie.Files.Add(SelectedMediaItem.FullPath);
                oSelectedMovie.Name = ctlMovieEditor.txtTitle.Text;
                if (ctlMovieEditor.txtYear.Text != String.Empty)
                    oSelectedMovie.Year = int.Parse(ctlMovieEditor.txtYear.Text);
                else
                    oSelectedMovie.Year = 0;
            }

            // Check if Audio-Info is present.
            if (oSelectedMovie.AudioInfo == null || oSelectedMovie.AudioInfo.Channels == 0)
            {
                // Fetch Audio-Info.
                ctlMovieEditor.ctlAudioInfo.AnalyseAudio();
            }

            // Check if Video-Info is present.
            if (oSelectedMovie.VideoInfo == null || oSelectedMovie.VideoInfo.VideoTracks == 0)
            {
                // Fetch Video-Info.
                ctlMovieEditor.ctlVideoInfo.AnalyseVideo();
            }

            SelectedMediaItem.UserdefinedMediaInfo = oSelectedMovie;
        }

        /// <summary>
        /// Show MediaInfo-Editor for Series.
        /// </summary>
        private void showEpisodeEditor()
        {
            Controls.Library.Import_Episode ctlEpisodeEditor = new XMM.Controls.Library.Import_Episode(this, SelectedMediaItem);
            spnItemDetails.Children.Add(ctlEpisodeEditor);

            ctlEpisodeEditor.ctlAudioInfo.SelectedFilePath = SelectedMediaItem.FullPath;
            ctlEpisodeEditor.ctlVideoInfo.SelectedFilePath = SelectedMediaItem.FullPath;

            // Get episode-info.
            if (SelectedMediaItem.UserdefinedMediaInfo.GetType() != typeof(Objects.SeriesEpisode))
                SelectedMediaItem.UserdefinedMediaInfo = new Objects.SeriesEpisode();

            Objects.SeriesEpisode oSelectedEpisode = (Objects.SeriesEpisode)SelectedMediaItem.UserdefinedMediaInfo;

            if (oSelectedEpisode == null || oSelectedEpisode.SeriesID == 0)
            {
                oSelectedEpisode = new Objects.SeriesEpisode();
                oSelectedEpisode.MediaFile = SelectedMediaItem.FullPath;
                if(ctlEpisodeEditor.cmbSeries.SelectedIndex > -1)
                    oSelectedEpisode.SeriesID = ((Objects.Series)ctlEpisodeEditor.cmbSeries.SelectedItem).SeriesID;
                if(ctlEpisodeEditor.cmbSeason.SelectedIndex > -1)
                    oSelectedEpisode.SeasonID = ((Objects.SeriesSeason)ctlEpisodeEditor.cmbSeason.SelectedItem).SeasonID;
            }

            if (oSelectedEpisode.AudioInfo == null || oSelectedEpisode.AudioInfo.Channels == 0)
            {
                // Fetch Audio-Info.
                ctlEpisodeEditor.ctlAudioInfo.AnalyseAudio();
            }

            if (oSelectedEpisode.VideoInfo == null || oSelectedEpisode.VideoInfo.VideoTracks == 0)
            {
                // Fetch Video-Info.
                ctlEpisodeEditor.ctlVideoInfo.AnalyseVideo();
            }

            SelectedMediaItem.UserdefinedMediaInfo = oSelectedEpisode;
        }

        /// <summary>
        /// Set MediaType-Selector to loaded MediaType-Info.
        /// </summary>
        /// <param name="iMediaType">(int) Media-Type.</param>
        private void setTypeSelection(int iMediaType)
        {
            switch (iMediaType)
            {
                case 1:
                    rdbMovie.IsChecked = true;
                    break;
                case 2:
                    rdbSeries.IsChecked = true;
                    break;
            }
        }

        /// <summary>
        /// Media-Type changed to movie.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void rdbMovie_Checked(object sender, RoutedEventArgs e)
        {
            if (bPreloading == false && SelectedMediaItem != null)
            {
                SelectedMediaItem.MediaType = 1;
            }

            ReloadItemImporter();
        }

        /// <summary>
        /// Media-Type changed to series.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void rdbSeries_Checked(object sender, RoutedEventArgs e)
        {
            if (bPreloading == false && SelectedMediaItem != null)
            {
                SelectedMediaItem.MediaType = 2;
            }

            ReloadItemImporter();
        }


        private void ReloadItemImporter()
        {
            if(spnItemDetails != null)
                spnItemDetails.Children.Clear();

            if (SelectedMediaItem != null)
            {
                if (SelectedMediaItem.MediaType == 1) // Movie
                {
                    showMovieEditor();
                }
                else if (SelectedMediaItem.MediaType == 2) // Episode
                {
                    showEpisodeEditor();
                }
            }
        }

        public void updateSelected(Objects.MediaInfo oMediaInfo)
        {
            if (lvFoundItems.SelectedItem != null)
            {
                int iSelectedIndex = lvFoundItems.SelectedIndex;
                _FileCollection[lvFoundItems.SelectedIndex] = oMediaInfo;
                lvFoundItems.Items.Refresh();
            }
        }

        private void btnImportMedia_Click(object sender, RoutedEventArgs e)
        {
            prepareImport();
        }

        private void prepareImport()
        {
            if (FileCollection != null && FileCollection.Count > 0)
            {
                try
                {
                    foreach (Objects.MediaInfo oMediaInfo in FileCollection)
                    {
                        if (oMediaInfo.IsEdited)
                        {
                            importMedia(oMediaInfo);
                        }
                    }
                }
                catch (InvalidOperationException ex)
                {
                    prepareImport();
                }
            }
            else
            {
                System.Windows.MessageBox.Show("Es wurde keine Datei gefunden!", "Keine Datei gefunden!", MessageBoxButton.OK, MessageBoxImage.Exclamation);
            }
        }

        private void importMedia(Objects.MediaInfo oMediaInfo)
        {
            switch (oMediaInfo.MediaType)
            {
                case 1: // Import as Movie-Object
                    importMovie(oMediaInfo);
                    break;
                case 2: // Import as Series-Episode
                    importEpisode(oMediaInfo);
                    break;
            }
        }

        private void importEpisode(Objects.MediaInfo oMediaInfo)
        {
            if (oMediaInfo.NewFile)
            {
                // Save as new Episode-Object.
                try
                {
                    // Initialize DB-Connection
                    XMMDBDataContext dbConnection = new XMMDBDataContext();

                    // Get Episode-Info.
                    Objects.SeriesEpisode oEpisodeInfo = (Objects.SeriesEpisode)oMediaInfo.UserdefinedMediaInfo;

                    if (oEpisodeInfo.SeasonID == 0)
                    {
                        System.Windows.MessageBox.Show("Die Datei \"" + oEpisodeInfo.MediaFile + "\" wurde nicht importiert: Keine Staffel angegeben.", "Fehlende Staffel", MessageBoxButton.OK, MessageBoxImage.Exclamation);
                        return;
                    }

                    if (oEpisodeInfo.EpisodeNo == 0)
                    {
                        System.Windows.MessageBox.Show("Die Datei \"" + oEpisodeInfo.MediaFile + "\" wurde nicht importiert: Keine Folgen-Nummer angegeben.", "Fehlende Staffel", MessageBoxButton.OK, MessageBoxImage.Exclamation);
                        return;
                    }

                    // Generate DB-Record.
                    t_series_episodes vNewEpisode = new t_series_episodes();

                    // Fill Values in new (unsaved) DB-Record.
                    vNewEpisode.Files = oEpisodeInfo.MediaFile;
                    vNewEpisode.Name = oEpisodeInfo.Name;
                    vNewEpisode.SeriesID = oEpisodeInfo.SeriesID;
                    vNewEpisode.SeasonID = oEpisodeInfo.SeasonID;
                    vNewEpisode.EpisodeNo = oEpisodeInfo.EpisodeNo;
                    vNewEpisode.Plot = oEpisodeInfo.Plot;
                    vNewEpisode.AudioInfo = oEpisodeInfo.AudioInfo.ToBinary();
                    vNewEpisode.VideoInfo = oEpisodeInfo.VideoInfo.ToBinary();
                    vNewEpisode.DiskMediaID = oEpisodeInfo.DiskMediaID;
                    vNewEpisode.HDLevel = oEpisodeInfo.HDLevel;
                    
                    // Submit Database-Object.
                    dbConnection.t_series_episodes.InsertOnSubmit(vNewEpisode);
                    dbConnection.SubmitChanges();

                    // Remove from list of found files.
                    _FileCollection.Remove(oMediaInfo);

                }
                catch (Exception ex)
                {
                    System.Windows.MessageBox.Show("Fehler beim Speichern der Episode: " + ex.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error);
                }
            }
            else
            {
                // Ask to update existing record...

                // Needs more code...
            }
        }

        private void importMovie(Objects.MediaInfo oMediaInfo)
        {
            if (oMediaInfo.NewFile)
            {
                // Save as new movie-object.
                try
                {
                    // Create Database-Object.
                    Objects.Movie oMovieInfo = (Objects.Movie)oMediaInfo.UserdefinedMediaInfo;
                    XMMDBDataContext dbConnection = new XMMDBDataContext();

                    t_movies vNewMovie = new t_movies();
                    vNewMovie.Name = oMovieInfo.Name;
                    vNewMovie.Subtitle = oMovieInfo.Subtitle;
                    vNewMovie.Plot = oMovieInfo.Plot;
                    vNewMovie.Cast = oMovieInfo.Cast;
                    vNewMovie.Year = oMovieInfo.Year;
                    vNewMovie.GenreID = oMovieInfo.GenreID;
                    vNewMovie.Director = oMovieInfo.Director;
                    vNewMovie.AudioInfo = oMovieInfo.AudioInfo.ToBinary();
                    vNewMovie.VideoInfo = oMovieInfo.VideoInfo.ToBinary();
                    vNewMovie.DiskMediaID = oMovieInfo.DiskMediaID;

                    // Add Files
                    string sFilePaths = String.Empty;
                    foreach (string sFilePath in oMovieInfo.Files)
                    {
                        sFilePaths += sFilePath + ";";
                    }
                    vNewMovie.Files = sFilePaths;

                    // Submit Database-Object.
                    dbConnection.t_movies.InsertOnSubmit(vNewMovie);
                    dbConnection.SubmitChanges();

                    // Add Cover-Art (if any) to image-libary.
                    if (oMediaInfo.CoverImagePath != String.Empty)
                    {
                        // Check if CoverArt-Image exists.
                        if (System.IO.File.Exists(oMediaInfo.CoverImagePath))
                        {
                            // Get Settings-Object
                            Settings oSettings = new Settings();

                            // Set Target Path for large Image
                            // [FileLibraryPath] + movies\\xmm_[PrimaryFileName].jpg
                            string sTargetImagePath = oSettings.LibraryDataStorage + "movies\\images\\xmm_" + oMediaInfo.FileName + ".jpg";

                            // Set Target Path for thumbnail image.
                            string sTargetThumbnailPath = oSettings.LibraryDataStorage + "movies\\thumb\\xmm_" + oMediaInfo.FileName + ".jpg";

                            // Create new files
                            try
                            {
                                if (File.Exists(sTargetImagePath))
                                    File.Delete(sTargetImagePath);
                                if (File.Exists(sTargetThumbnailPath))
                                    File.Delete(sTargetThumbnailPath);

                                // Copy large version
                                File.Copy(oMediaInfo.CoverImagePath, sTargetImagePath);

                                // Create thumbnail
                                System.Drawing.Bitmap bmpLargeImage = new System.Drawing.Bitmap(oMediaInfo.CoverImagePath);
                                System.Drawing.Bitmap bmpThumbnail = Functions.Imaging.ResizeBitmap(bmpLargeImage, (int)(bmpLargeImage.Width / 10), (int)(bmpLargeImage.Height / 10));

                                FileStream fsOutput = System.IO.File.Create(sTargetThumbnailPath);
                                bmpThumbnail.Save(fsOutput, System.Drawing.Imaging.ImageFormat.Jpeg);
                                fsOutput.Flush();
                                fsOutput.Close();
                                fsOutput.Dispose();

                                spnItemDetails.Children.Clear();
                                spnMediaType.Visibility = System.Windows.Visibility.Collapsed;
                            }
                            catch (IOException ex)
                            {
                                System.Windows.MessageBox.Show("Fehler beim Speichern der Bilder für \"" + oMovieInfo.Name + "\": " + ex.Message + Environment.NewLine + Environment.NewLine + "Der Film wird ohne CoverArt importiert.", "Fehler in CoverArt", MessageBoxButton.OK, MessageBoxImage.Warning);
                            }
                        }
                    }

                    // Remove from list of found files.
                    _FileCollection.Remove(oMediaInfo);
                }
                catch (Exception ex)
                {
                    System.Windows.MessageBox.Show("Fehler beim Importieren der Datei \"" + oMediaInfo.FullPath + "\": " + ex.Message, "Fehler", MessageBoxButton.OK, MessageBoxImage.Error);
                }
            }
            else
            {
                // Ask to update existing object.

                // Needs more code...
            }
        }

        private void btnCloseImportDialog_Click(object sender, RoutedEventArgs e)
        {
            ParentMainWindow.RefreshXMM();
            Tools.clearTemp();
            Close();
        }

        public void ApplyForAll(Objects.SeriesEpisode oEpisodeInfo)
        {
            int iUpdatedItems = 0;

            foreach (Objects.MediaInfo oMediaInfo in _FileCollection)
            {
                if (oMediaInfo.IsEdited == false)
                {
                    Objects.SeriesEpisode oTemplateEpisode = new Objects.SeriesEpisode();
                    oTemplateEpisode.SeriesID = oEpisodeInfo.SeriesID;
                    oTemplateEpisode.SeasonID = oEpisodeInfo.SeasonID;
                    oTemplateEpisode.DiskMediaID = oEpisodeInfo.DiskMediaID;
                    oTemplateEpisode.MediaFile = oMediaInfo.FullPath;
                    oTemplateEpisode.EpisodeNo = Functions.StringManipulation.getEpisodeNoFromFileName(oTemplateEpisode.MediaFile);
                    oTemplateEpisode.AudioInfo = oMediaInfo.File0AudioInfo;
                    oTemplateEpisode.VideoInfo = oMediaInfo.File0VideoInfo;

                    _FileCollection[_FileCollection.IndexOf(oMediaInfo)].UserdefinedMediaInfo = oTemplateEpisode;
                    _FileCollection[_FileCollection.IndexOf(oMediaInfo)].IsEdited = true;
                    _FileCollection[_FileCollection.IndexOf(oMediaInfo)].MediaType = 2;
                    ++iUpdatedItems;
                }
            }

            lvFoundItems.Items.Refresh();
            System.Windows.MessageBox.Show(iUpdatedItems.ToString() + " Einträge aktualisiert!", "Infos übernommen", MessageBoxButton.OK, MessageBoxImage.Information);
        }

        

    }
}
